#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include "time.h"

#define uint32_t  unsigned int

struct SpiMsg {
    unsigned char *wbuf;       /**< Address of the write buffer */
    unsigned char *rbuf;       /**< Address of the read buffer */
    uint32_t len;        /**< Length of the read and write buffers. The read buffer and the write
                          * buffer have the same length.
                          */
    uint32_t speed;      /**< Current message transfer speed */
    unsigned short delayUs;    /**< Delay (in microseconds) before starting the next transfer.
                          * The value <b>0</b> indicates there is no delay between transfers.
                          */
    unsigned char keepCs;    /**< Whether to keep CS active after current transfer has been
                          * completed. <b>1</b> indicates to keeps CS; <b>0</b> indicates to switch off the CS.
                          */
};

struct SpiIocMsg {
    struct SpiMsg *msg;
    int count;
};

#define SPI_CPHA		0x01
#define SPI_CPOL		0x02

#define SPI_MODE_0		(0|0)
#define SPI_MODE_1		(0|SPI_CPHA)
#define SPI_MODE_2		(SPI_CPOL|0)
#define SPI_MODE_3		(SPI_CPOL|SPI_CPHA)

#define SPI_IOC_MAGIC 'k'
#define SPI_IOC_MESSAGE                 _IOW(SPI_IOC_MAGIC, 0, struct SpiIocMsg)
#define SPI_IOC_RD_MODE                 _IOR(SPI_IOC_MAGIC, 1, uint32_t)
#define SPI_IOC_RD_LSB_FIRST            _IOR(SPI_IOC_MAGIC, 2, uint32_t)
#define SPI_IOC_RD_BITS_PER_WORD        _IOR(SPI_IOC_MAGIC, 3, uint32_t)
#define SPI_IOC_RD_MAX_SPEED_HZ         _IOR(SPI_IOC_MAGIC, 4, uint32_t)
#define SPI_IOC_WR_MODE                 _IOW(SPI_IOC_MAGIC, 1, uint32_t)
#define SPI_IOC_WR_LSB_FIRST            _IOW(SPI_IOC_MAGIC, 2, uint32_t)
#define SPI_IOC_WR_BITS_PER_WORD        _IOW(SPI_IOC_MAGIC, 3, uint32_t)
#define SPI_IOC_WR_MAX_SPEED_HZ         _IOW(SPI_IOC_MAGIC, 4, uint32_t)


typedef void (*irq_func)(unsigned int irq, void *data);

typedef struct GpioBitInfo {
    unsigned int  groupnumber;
    unsigned int  bitnumber;
    unsigned char value;
    unsigned char direction;
    unsigned char irq_status;
    unsigned char irq_enable;
    irq_func  irq_handler;
    unsigned int irq_type;
    void *data;
} gpio_groupbit_info;

#define GPIO_SET_DIR            _IOWR('w', 4, gpio_groupbit_info)
#define GPIO_GET_DIR            _IOWR('r', 5, gpio_groupbit_info)
#define GPIO_READ_BIT           _IOWR('r', 6, gpio_groupbit_info)
#define GPIO_WRITE_BIT          _IOWR('w', 7, gpio_groupbit_info)

//spidev0.0
#define DEV_NAME "/dev/spidev2.0"



int main(int argc, char **argv)
{
    printf("\n************************************************\n");
    int fd = 0;
    int gpiofd = 0;
    int ret = 0;
    int i = 0;

    unsigned short buf16[8] = {0};
    gpio_groupbit_info ctrl = {0};

    fd = open(DEV_NAME, O_RDWR);
    if(fd == 0){
        printf("open %s failed error: %d\n",DEV_NAME, fd);
        return -1;
    }else{
        printf("open %s sucess fd: %d\n",DEV_NAME, fd);
    }

    unsigned long arg = SPI_MODE_2;
    ioctl(fd, SPI_IOC_WR_MODE, &arg);
    arg = 50000000; 
    ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &arg);//设置传输频率

    gpiofd=open("/dev/gpio",O_RDWR);
    //set PH23
    ctrl.bitnumber=23;
    ctrl.groupnumber=7;
    ctrl.direction=1;
    ctrl.value=0;

    ioctl(gpiofd,GPIO_SET_DIR,&ctrl);
    printf("set PH23 out low \n");
    ioctl(gpiofd,GPIO_WRITE_BIT,&ctrl);
    ctrl.value=1;
    printf("set PH23 out high \n");
    ioctl(gpiofd,GPIO_WRITE_BIT,&ctrl);

    printf("read 8 chanel \n");
    read(fd,  buf16, 16);
    printf("%04x %04x %04x %04x %04x %04x %04x %04x \n", buf16[0], buf16[1], buf16[2], buf16[3], buf16[4], buf16[5], buf16[6], buf16[7]);
    printf("wait \n");
    getchar();

    ctrl.value=0;
    printf("set PH23 out low \n");
    ioctl(gpiofd,GPIO_WRITE_BIT,&ctrl);

    close(fd);
    close(gpiofd);
    printf("\n************************************************\n\n");
    
    return 0;
}